// ModelEntityGenerator.cpp: implementation of the ModelEntityGenerator class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "ModelEntityGenerator.h"
#include "dbents.h"
#include "UEEntityOperation.h"
#include "PartPoint.h"
#include "PipeGenerator.h"
#include "NewGeometryObject.h"
#include "JointPart.h"
#include "ModelGenerator.h"
#include "SHPoint.h"
#include "PartPoint.h"
#include "SupportHanger.h"
#include "UEEntityOperation.h"
#include "SHPoint.h"
#include "Joininfo.h"
#include "JointFunction.H"
#include "ManualJointGenerator.h"
#include "DlgModelParam.h"
#include "AttachMatrixFunction.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
using namespace JointSystem;
IMPLEMENT_SINGLETON(ModelEntityGenerator);

ModelEntityGenerator::ModelEntityGenerator()
{

}

ModelEntityGenerator::~ModelEntityGenerator()
{

}

AcDbEntity* ModelEntityGenerator::Generate(Part& part)
{
	AcDbEntity* pEnt = NULL;
	
	if(part.GetCustomID() == PipeGenerator::PipeID())
	{
		pEnt = new AcDbPoint();
	}
	else
	{		
		pEnt = ModelGenerator::Instance().GenerateEntityForPart( part );
	}
	return pEnt;
}

void ModelEntityGenerator::DrawAttach(Joint* pJoint)
{
	ASSERT(pJoint);
	ASSERT(pJoint->SupportHangerOwner());
	ASSERT(pJoint->GetPrev());
	ASSERT(pJoint->GetNext());

	JointPort* pPrev = pJoint->GetPrev()->jointPort();
	JointPort* pNext = pJoint->GetNext()->jointPort();

	AcGeMatrix3d csPrev = pJoint->GetPrev()->GetOwner()->ModelMatrix() 
		*pPrev->CoordinateInOwner();

	FunctionStack::Iterator* pIt = pJoint->GetFunctionStack()
		->GetFunction(FunctionObject::eJONTATTACHMATRIX);
	ASSERT_MEMORY_VALID(pIt, NORETURN);
	for(pIt->Begin(); !pIt->End(); pIt->Next())
	{
		FunctionObject* pObj = pIt->Get();
		ASSERT(pObj);
		ASSERT(pObj->IsKindOf(UE_RUNTIME_CLASS(AttachMatrixFunction)));

		AttachMatrixFunction* pFun = static_cast<AttachMatrixFunction*>(pObj);
		
		PropertySystem::PropertyVariable* pVar = pJoint->GetProperty(pFun->PartID());
		ASSERT(pVar);
		if(!pVar->IsEffect())
			pVar->InitValue();
		
		Part* pPart = (Part*)(*pVar);
		pPart->ModelMatrix(csPrev*pFun->Matrix());
	}
	delete pIt;
/*	pPrev->Coordinate(csPrev);
	Part* pPart = NULL;
	Joint::Iterator* pIt = pJoint->NewAttachIterator();
	for(pIt->Begin(); !pIt->End(); pIt->Next())
	{
		pPart = pIt->Get();
		ASSERT(pPart);
		pPart->EffectProperty();
		JointPart* jp = new JointPart;
		jp->PartFormatID( pPart->GetCustomID() );
		jp->CatalogID( pPart->GetStandard() );
		jp->SetProperties( pPart->GetPropertyStack() );
		jp->Format();
		jp->InitJointPorts();

		pPrev->AddAccessory(jp);
	}
	pPrev->Coordinate(csPrev);
	pNext->AttachToJointPort(pPrev);

	INT nIndex = 0;
	for(pIt->Begin(); !pIt->End(); pIt->Next())
	{
		pPart = pIt->Get();
		ASSERT(pPart);

		pPart->ModelMatrix(pPrev->GetAccessoryAt(nIndex)->Coordinate());
		nIndex++;

//		AcDbEntity* pEnt = Generate(*pPart);
//		ASSERT(pEnt);

//		Acad::ErrorStatus es = Acad::eOk;
//		es = pEnt->transformBy(pPart->ModelMatrix());
//		ASSERT(es == Acad::eOk);
//		es = pEnt->transformBy(pJoint->SupportHangerOwner()->ModelMatrix());
//		ASSERT(es == Acad::eOk);
//		es = CUEEntityOperation::AddEntityToDwg(pEnt, _T(""), FALSE);
//		ASSERT(es == Acad::eOk);
//		AcDbHandle handle;
//		pEnt->getAcDbHandle(handle);
//		ASSERT(!handle.isNull());
//		pEnt->close();

//		NewGeometryObject::Instance()->Generate(*pPart, handle);
//		pPart->SetNotUpdateObserver();
	}
	delete pIt;//*/
}